import java.io.*;
import java.util.*;

/**
 * The class to automatically generate the statistic in each metric against increasing value of control variable
 * to be displayed by the python script
 *
 */
public class processResult {
	enum metric
	{
		time,
		mem,
		error
	};
	enum control
	{
		size,
		dim
	};
	
	class stat
	{
		public String time;
		public String mem;
		public String error;
		
		public stat(String time, String mem, String error)
		{
			this.time = time;
			this.mem = mem;
			this.error = error;
		}
		
		public String get(metric m)
		{
			switch (m)
			{
				case error: return this.error;
				case mem: return this.mem;
				case time: return this.time;
			}
			return "";
		}
	}
	
	private List<File> AllFile;
	private String[] dimList = {"10000_10", "10000_50", "10000_100", "10000_500", "10000_1000", "10000_-1"};
	private String[] sizeList = {"100_1000", "500_1000", "1000_1000", "5000_1000", "10000_1000"};
	private stat[][] dimResult;
	private stat[][] sizeResult;
	private metric[] allMetric = {metric.time, metric.mem, metric.error};
	private String directory;
//	private control[] allControl = {control.size, control.dim};
	
	/**
	 * Print the result gathered to a single file, defined by the control variable and metric used
	 * a line per method, separated by commas (',')
	 */
	private void printAllResults(stat[][] data, control c, metric m)
	{
		if (data.length == 0) return;
		int len = data.length;
		int typeLen = data[0].length;
		
		String fileName = directory + "/data_";
		switch (m)
		{
			case error: fileName += "error_vs_"; break;
			case time: fileName += "time_vs_"; break;
			case mem: fileName += "mem_vs_"; break;
		}
		switch (c)
		{
			case dim: fileName += "dim.csv"; break;
			case size: fileName += "size.csv"; break;
		}
		
		try
		{
			PrintStream ps = new PrintStream(new FileOutputStream(fileName));
			for (int i = 0; i < typeLen; i++)
			{
				StringBuilder sb = new StringBuilder(data[0][i].get(m));
				for (int j = 1; j < len; j++)
				{
					if (i < data[j].length)
					{
						sb.append("," + data[j][i].get(m));
					}
				}
				ps.println(sb.toString());
			}
			ps.close();
		}
		catch (Exception ex)
		{
				System.out.println("Failed to write the result");
				ex.printStackTrace();
		}
	}
	
	/**
	 * Exhaustively search from the files in the directory for a matching target string
	 * @param target the file name to be retrieved from the list of file
	 * @return the file object that match the target file name
	 */
	private File searchList(String target)
	{
		int len = AllFile.size();
		for (int i = 0; i < len; i++)
		{
			File temp = AllFile.get(i);
			if (temp.getName().equals(target)) return temp;
		}
		return null;
	}
	
	/**
	 * 
	 * @param f the file to be read
	 * @return an array of stat containing time, memory, and error rate for a particular run
	 */
	private stat[] readContent(File f)
	{
		ArrayList<stat> retVal = new ArrayList<stat>();
		try
		{
			FileInputStream fin = new FileInputStream(f);
			BufferedReader is = new BufferedReader(new InputStreamReader(fin));		
	
			String line = null;
			while ((line = is.readLine()) != null)
			{
				String[] split = line.split(",");
				retVal.add(new stat(split[0], split[1], split[2]));
			}
		}
		catch (Exception ex)
		{
			System.out.println("File Not Found : " + f.getName());
			System.exit(1);
		}
		return retVal.toArray(new stat[retVal.size()]);
	}
	
	/**
	 * Read the content of the file that match the name described in dimList or sizeList
	 */
	public void read()
	{
		for (int i = 0; i < dimList.length; i++)
		{
			dimResult[i] = readContent(searchList("stat_" + dimList[i] + ".csv"));
			
		}
		for (int i = 0; i < sizeList.length; i++)
		{
			sizeResult[i] = readContent(searchList("stat_" + sizeList[i] + ".csv"));
		}
	}
	
	/**
	 * Print the processed results to a file
	 */
	public void write()
	{
		for(int i = 0; i < allMetric.length; i++)
		{
			printAllResults(dimResult, control.dim, allMetric[i]);
			printAllResults(sizeResult, control.size, allMetric[i]);
		}
	}
	
	public processResult(String directory)
	{
		this.directory = directory;
		FileReader fr = new FileReader();
		fr.readFiles(directory);
		AllFile = fr.getFiles();
		
		dimResult = new stat[dimList.length][];
		sizeResult = new stat[sizeList.length][];
	}
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		processResult processer = new processResult("test");
		processer.read();
		processer.write();
	}

}
